home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
et
/
et3_0-a1.lha
/
et3
/
src
/
Class.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-06-09
|
4KB
|
200 lines
#ifdef __GNUG__
#pragma implementation
#endif
#include "Class.h"
#include "Error.h"
#include "Storage.h"
#include "String.h"
#include "ObjArray.h"
#include "OrdColl.h"
#include "ObjectTable.h"
#include "ClassManager.h"
#include "AccessMem.h"
//---- Class -------------------------------------------------------------------
NewMetaImpl(Class,Object, (TP(version), TP(super), TP(className), T(size),
TP(proto), TS(declFileName), T(declFileLine), TS(implFileName),
T(implFileLine), TP(subclasses), T(instanceCount), TP(methods)));
Class *Class::classptr;
#ifdef ET_
static char *EtPrefix= _QUOTE_(ET_);
#else
static char *EtPrefix= "";
#endif
Class::Class(char *name, int sz, Object *pro, char *implfn, char *declfn,
int il, int dl, bool abstract)
{
size= sz;
className= name;
if (strncmp(name, EtPrefix, sizeof(EtPrefix)-1) == 0)
className= &name[sizeof(EtPrefix)-1];
declFileName= declfn;
implFileName= implfn;
declFileLine= dl;
implFileLine= il;
proto= pro;
subclasses= 0;
instanceCount= 0;
methods= 0;
version= "2.2";
if (abstract)
SetFlag(eClassAbstract);
if (gClassManager == 0)
gClassManager= new ClassManager;
gClassManager->Add(this);
if (proto)
SetFlag(eClassObject);
classptr= 0;
}
Class::Class(char *name, char *vers)
{
className= name;
version= vers;
proto= 0;
methods= 0;
subclasses= 0;
}
Class::~Class()
{
if (proto) {
delete (void*) proto; // avoid call of destructor for prototype
proto= 0;
}
if (methods) {
methods->FreeAll();
SafeDelete(methods);
}
SafeDelete(subclasses);
if (gClassManager)
gClassManager->Remove(this);
}
//---- class hierarchy ---------------------------------------------------------
Class *Class::SetSuper()
{
super= classptr;
classptr= this;
return this;
}
bool Class::isKindOf(register Class *c)
{
register Class *cc;
for (cc= this; cc; cc= cc->super)
if (cc == c)
return TRUE;
return FALSE;
}
void Class::AddSubclass(Class *cl)
{
if (subclasses == 0)
subclasses= new OrdCollection;
subclasses->Add(cl);
}
Iterator *Class::SubclassIterator()
{
if (subclasses == 0)
subclasses= new OrdCollection;
return subclasses->MakeIterator();
}
//---- comparing ---------------------------------------------------------------
u_long Class::Hash()
{
register u_long hash;
register char *p= className;
for (hash= 0; *p; p++)
hash= (hash << 1) ^ *p;
return hash;
}
bool Class::IsEqual(Object *op)
{
//return strcmp(className, ((Class*)op)->className) == 0
// && strcmp(version, ((Class*)op)->version) == 0;
return strcmp(className, ((Class*)op)->className) == 0;
}
int Class::Compare(Object *op)
{
//int rc= strcmp(className, ((Class*)op)->className);
//if (rc)
// return rc;
//return strcmp(version, ((Class*)op)->version);
return strcmp(className, ((Class*)op)->className);
}
//---- converting, input/output ------------------------------------------------
char* Class::AsString()
{
return className;
}
void Class::Show(char *buf, void *addr, int, bool isptr)
{
if (isptr) {
if (ObjectTable::PtrIsValid((Object*)addr))
sprintf(buf, "<%s>", ((Object*)addr)->ClassName());
} else
sprintf(buf, "<inline>");
}
OStream &Class::PrintOn(OStream &os)
{
return os << className SP << version SP;
}
// always called on prototype object !!!
Object *Class::ReadAndMap(IStream &is)
{
char name[40], vers[40];
is >> name >> vers;
return gClassManager->FindOrLoad(name, vers);
}
//---- members -----------------------------------------------------------------
Object *Class::SomeMember()
{
return ObjectTable::SomeMember(this);
}
void Class::EnumerateMyMembers(AccessMembers *ac)
{
if (className && ac)
ac->ClassName(className);
if (proto)
proto->Members(ac);
}
void Class::EnumerateMembers(AccessMembers *ac)
{
EnumerateMyMembers(ac);
if (super)
super->EnumerateMembers(ac);
}
//---- instance statistics -----------------------------------------------------
Object *Class::SomeInstance()
{
return ObjectTable::SomeInstance(this);
}